#include <iostream>
#include <pthread.h>
#include <string>
#include <unistd.h>

pthread_mutex_t glock = PTHREAD_MUTEX_INITIALIZER;

class ThreadDate
{
public:
    ThreadDate(const std::string n, pthread_mutex_t &lock)
        : name(n),
          lockp(&lock)
    {
    }
    ~ThreadDate() {}


    std::string name;
    pthread_mutex_t *lockp;
};

int ticket = 1000;
void *routine(void *args)
{
    ThreadDate* td = static_cast<ThreadDate*>(args);
    while (true)
    {
        // pthread_mutex_lock(&glock);
        pthread_mutex_lock(td->lockp);
        if (ticket > 0)
        {
            usleep(1000);
            printf("%s sells ticket:%d\n", td->name.c_str(), ticket);
            ticket--;
            // pthread_mutex_unlock(&glock);
            pthread_mutex_unlock(td->lockp);
        }
        else
        {
            // pthread_mutex_unlock(&glock);
            pthread_mutex_unlock(td->lockp);
            break;
        }
    }
    return nullptr;
}

int main()
{
    pthread_mutex_t lock;
    pthread_mutex_init(&lock,nullptr);
    pthread_t tid1;
    pthread_t tid2;
    pthread_t tid3;
    pthread_t tid4;

    ThreadDate* td1 = new ThreadDate("thread 1",lock);
    pthread_create(&tid1, nullptr, routine, td1);

    ThreadDate* td2 = new ThreadDate("thread 2",lock);
    pthread_create(&tid2, nullptr, routine, td2);

    ThreadDate* td3 = new ThreadDate("thread 3",lock);
    pthread_create(&tid3, nullptr, routine, td3);

    ThreadDate* td4 = new ThreadDate("thread 4",lock);
    pthread_create(&tid4, nullptr, routine, td4);

    pthread_join(tid1, nullptr);
    pthread_join(tid2, nullptr);
    pthread_join(tid3, nullptr);
    pthread_join(tid4, nullptr);

    pthread_mutex_destroy(&lock);

    return 0;
}